// 题意：给定n个房间每个房间会有一个插口，有m个不同的设备，需要相应的插口，
//       还有k个适配器，适配器可以插在某个插口上提供新的插口，每个适配器可以使用无数次。
//       加入一个房间通过使用一些适配器，只能供一个设备插，问最少有几个设备没得插。
//
// 题解：比较简单的二分图匹配...就是构图稍微麻烦点，，不过数据很小，随便怎么构都行。
//
// run: time $exec < input
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>

struct bipartite_graph
{
	typedef int size_type;
	typedef std::vector<size_type> edge_type;
	typedef std::vector<size_type>::iterator edge_iter;
	typedef std::vector<edge_type> graph_type;

	// [0, n)
	// for even node black, {0, 2, 4, ...}
	//      odd node white, {1, 3, 5, ...}
	bipartite_graph(size_type n)
	{
		graph.resize(n);
		linked.resize(n);
		visited.resize(n);
	}

	void add_edge(size_type x, size_type y)
	{
		graph[x].push_back(y); graph[y].push_back(x);
	}

	bool hungarian_dfs(size_type u)
	{
		for (edge_iter it = graph[u].begin(); it != graph[u].end(); ++it) {
			size_type v = *it;
			if (visited[v]) continue;
			visited[v] = true;
			if (linked[v] == -1 || hungarian_dfs(linked[v])) {
				linked[u] = v; linked[v] = u;
				return true;
			}
		}
		return false;
	}

	size_type max_match()
	{
		size_type n = graph.size();
		std::fill(linked.begin(), linked.end(), -1);
		size_type bi_match = 0;
		for (size_type i = 0; i < n; i += 2) {
			std::fill(visited.begin(), visited.end(), false);
			if (hungarian_dfs(i)) bi_match++;
		}
		return bi_match;
	}

private:
	graph_type graph;
	edge_type linked;
	std::vector<bool> visited;
};


int const maxn = 407;
int room[maxn];
int device[maxn];
bool vis[maxn];
int n, m, k, tot_receptacle, tot_device;

typedef std::map<std::string, int> map_type;
map_type receptacle_index;
map_type device_index;

typedef std::vector<int> adj_edge;
typedef adj_edge::iterator edge_iter;
typedef std::vector<adj_edge> graph_type;
graph_type graph(maxn);
graph_type adapter(maxn);

int get_map_index(map_type & map_index, std::string const & s, int & index)
{
	if (map_index.find(s) == map_index.end())
		map_index[s] = index++;
	return map_index[s];
}

void dfs(int s, int u)
{
	vis[s] =  true;
	graph[s].push_back(u);
	for (edge_iter it = adapter[u].begin(); it != adapter[u].end(); ++it)
		if (!vis[*it]) dfs(s, *it);
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n;
	for (int i = 0; i < n; i++) {
		std::string s;
		std::cin >> s;
		room[i] = get_map_index(receptacle_index, s, tot_receptacle);
	}

	std::cin >> m;
	for (int i = 0; i < m; i++) {
		std::string s1, s2;
		std::cin >> s1 >> s2;
		int u = get_map_index(receptacle_index, s2, tot_receptacle);
		device[i] = u;
	}

	std::cin >> k;
	for (int i = 0; i < k; i++) {
		std::string s1, s2;
		std::cin >> s1 >> s2;
		int u = get_map_index(receptacle_index, s2, tot_receptacle);
		int v = get_map_index(receptacle_index, s1, tot_receptacle);
		adapter[v].push_back(u);
	}

	for (int i = 0; i < tot_receptacle; i++) {
		std::memset(vis, 0, sizeof(vis));
		dfs(i, i);
	}

	/*
	std::cout << "----graph\n";
	for (int i = 0; i < tot_receptacle; i++) {
		for (auto j : graph[i]) std::cout << j << ' ';
		std::cout << '\n';
	}
	std::cout << "----graph\n";
	*/

	bipartite_graph bg(2 * (std::max(m, n) + 1));
	for (int i = 0; i < m; i++) {
		int u = device[i];
		for (int j = 0; j < n; j++) {
			int v = room[j];
			bool opt = false;
			for (edge_iter it = graph[u].begin(); it != graph[u].end(); ++it)
				if (*it == v) { opt = true; break; }
			if (opt) bg.add_edge(2 * i, 2 * j + 1);
		}
	}

	std::cout << m - bg.max_match() << '\n';
}

